/**
*  deferredconfirm.cpp
*
*  @copyright 2016
*/

/**
*  Dependencies
*/
#include "DeferredReturn.h"
#include "basicheaderframe.h"
#include "bodyframe.h"
#include "basicreturnframe.h"

/**
*  Start namespace
*/
namespace AMQP {

	/**
	*  Process the return headers
	*
	*  @param  frame   The frame to process
	*/
	void DeferredReturn::process(BasicReturnFrame &frame)
	{
		// retrieve the _replyCode and _replyText
		_replyCode = frame.replyCode();
		_replyText = frame.replyText();

		// anybody interested in the new message?
		if (_beginCallback)   _beginCallback();

		// do we have anybody interested in messages?
		if (_returnCallback) _message.construct(frame.exchange(), frame.routingKey());
	}

	/**
	*  Indicate that a message was done
	*/
	void DeferredReturn::complete()
	{
		// make sure we stay in scope
		auto self = shared_from_this();

		// do we have a message?
		if (_message)
		{
			// emit the message
			emit(std::move(*_message), _replyCode, _replyText);

			// and destroy it
			_message.reset();
		}

		// do we have to inform anyone about completion?
		if (_completeCallback) _completeCallback(_replyCode, _replyText);

		// we are now done executing
		auto &channel_val = _channel.lock();
		if (channel_val && channel_val.get())
			channel_val->complete();
	}

	void DeferredReturn::emit(Message &&message, int16_t replyCode, const std::string& replyText) const
	{
		_returnCallback(std::move(message), replyCode, replyText);
	}
}